package com.qingfeng.framework.filter;

import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qingfeng.util.Json;
import com.qingfeng.util.PageData;
import com.qingfeng.util.Verify;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;

public class CsrfFilter extends OncePerRequestFilter {
    private Collection<String> domains;

    public CsrfFilter(Collection<String> domains) {
        this.domains = domains;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        HttpSession session = request.getSession();
        //处理数据权限
        System.out.println("------------88888-----------------");
        Enumeration headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String key = (String) headerNames.nextElement();
            String value = request.getHeader(key);
            System.out.println(key+":"+value);
        }
        System.out.println(request.getParameter("token"));
        System.out.println("-----------------------------");
        System.out.println(request.getHeader("access-token"));
        String  token = request.getHeader("access-token");
        if(Verify.verifyIsNotNull(token)) {
            // GET 等方式不用提供Token，自动放行，不能用于修改数据。修改数据必须使用 POST、PUT、DELETE、PATCH 方式并且Referer要合法。
            if (Arrays.asList("GET", "HEAD", "TRACE", "OPTIONS").contains(request.getMethod())) {
                filterChain.doFilter(request, response);
                return;
            }
            if (!domains.isEmpty() && !verifyDomains(request)) {
//                response.sendError(HttpServletResponse.SC_FORBIDDEN, "CSRF Protection: Referer Illegal");
                Json json = new Json();
                json.setSuccess(false);
                json.setMsg("CSRF 保护：Referer 非法");
                response.setContentType("text/html;charset=utf-8");
                ObjectMapper objMapper = new ObjectMapper();
                JsonGenerator jsonGenerator = objMapper.getJsonFactory()
                        .createJsonGenerator(response.getOutputStream(),
                                JsonEncoding.UTF8);
                jsonGenerator.writeObject(json);
                jsonGenerator.flush();
                jsonGenerator.close();
                return;
            }
        }

        filterChain.doFilter(request, response);
    }

    private boolean verifyDomains(HttpServletRequest request) {
        // 从 HTTP 头中取得 Referer 值
        String referer = request.getHeader("Referer");
        // 判断 Referer 是否以 合法的域名 开头。
        if (referer != null) {
            // 如 http://mysite.com/abc.html https://www.mysite.com:8080/abc.html
            if (referer.indexOf("://") > 0) referer = referer.substring(referer.indexOf("://") + 3);
            // 如 mysite.com/abc.html
            if (referer.indexOf("/") > 0) referer = referer.substring(0, referer.indexOf("/"));
            // 如 mysite.com:8080
            if (referer.indexOf(":") > 0) referer = referer.substring(0, referer.indexOf(":"));
            // 如 mysite.com
            for (String domain : domains) {
                if (referer.contains(domain)) return true;
            }
        }
        return false;
    }

    private boolean verifyToken(HttpServletRequest request, String token) {
        return token.equals(request.getParameter("csrfToken"));
    }
}
